# 在APP中创建consumers.py文件，相当于创建视图文件
import logging
import os
from threading import current_thread

from asgiref.sync import async_to_sync
from channels.exceptions import StopConsumer
from channels.generic.websocket import WebsocketConsumer
log = logging.getLogger("__name__")

class ChatConsumer(WebsocketConsumer):

    def websocket_connect(self, message):
        # 有客户端向后端发送socket连接的请求时，触发函数
        group = self.scope['url_route']['kwargs'].get('group')
        log.info(os.getpid())
        self.accept()  # 允许创建连接
        log.info(f"收到socket链接：{self},添加到channels组：{group}")
        async_to_sync(self.channel_layer.group_add)(group, self.channel_name)

    def websocket_receive(self, message):
        log.info(f"收到消息：{message}")

    def xx_oo(self, event):  # 方法名.转换为_
        text = event['message']  # event 为上面方法传入的字典
        self.send(text)  # 此时self不指当前连接，而是上面组中的每一个连接对象
        log.info(f"发送广播消息：{text}")
        if text == "close":
            log.info(f"通知客户端关闭连接：{self}")
            self.close()

    def websocket_disconnect(self, message):
        group = self.scope['url_route']['kwargs'].get('group')
        # 客户端与服务器断开连接时，自动触发，服务端断开连接也会默认执行
        # 如果不想服务端断开连接也自动执行，要在self.close()后面加上raise StopConsumer()
        # self.close() 这个函数是服务端主动断开连接，给客户端发送断开连接的消息
        async_to_sync(self.channel_layer.group_discard)(group, self.channel_name)
        log.info(f"关闭连接：{self},从组{group}中移除")
        raise StopConsumer()
